package com.hksj.em.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hksj.base.entity.Properties;
import com.hksj.base.service.DefaultDeviceService;
import com.hksj.base.vo.ChartVO;
import com.hksj.base.vo.DeviceVO;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.common.core.util.EasyExcelUtil;
import com.hksj.em.enums.PropertyEnum;
import com.hksj.em.mapper.RoomEnvMapper;
import com.hksj.em.query.RoomEnvChartQuery;
import com.hksj.em.query.RoomEnvQuery;
import com.hksj.em.query.RoomEnvRecordQuery;
import com.hksj.em.vo.*;
import com.hksj.tdengine.taos.service.TaosService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class RoomEnvService {
    @Autowired
    private RoomEnvMapper roomEnvMapper;
    @Autowired
    private DefaultDeviceService defaultDeviceService;

    @Value(value = "${hk.td-engine.db-name:''}")
    private String tdEngineDbName;

    @Autowired
    private TaosService taosService;

    public IPage<RoomEnvVO> pageRoomEnv(RoomEnvQuery query) {
        Page<RoomEnvVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        List<RoomEnvVO> roomList = roomEnvMapper.listRoom(query,query.getDisAblePage() ? null : page);
        if (!ObjectUtils.isEmpty(roomList)){
            List<Long> roomIdList = roomList.stream().map(RoomEnvVO::getRoomId).collect(Collectors.toList());
            query.setRoomIdList(roomIdList);
            query.setSpecialityCode(null);
            List<RoomDevicePropertyVO> devicePropertyList = roomEnvMapper.listRoomDeviceProperty(query);

//            //查询灯带
//            List<RoomLightStatusVO> lightList = roomEnvMapper.listLightDevice(roomIdList);
//            Map<Long, List<RoomLightStatusVO>> roomLightMap = new HashMap<>();
//            if (!ObjectUtils.isEmpty(lightList)){
//                roomLightMap = lightList.stream().collect(Collectors.groupingBy(RoomLightStatusVO::getRoomId));
//            }
//
//            //查空调设备
//            List<RoomAirConditionSwitchVO> airConditionSwitchList = roomEnvMapper.listAirConditionDevice(roomIdList);
//            Map<Long, RoomAirConditionSwitchVO> roomAirConditionSwitchMap = new HashMap<>();
//            if (!ObjectUtils.isEmpty(airConditionSwitchList)){
//                roomAirConditionSwitchMap = airConditionSwitchList.stream().collect(Collectors.toMap(RoomAirConditionSwitchVO::getRoomId, Function.identity()));
//            }

            if (!ObjectUtils.isEmpty(devicePropertyList)){
                Map<Long, Map<String, RoomDevicePropertyVO>> roomPropertyMap = devicePropertyList.stream().collect(Collectors.groupingBy(RoomDevicePropertyVO::getRoomId,
                        Collectors.toMap(RoomDevicePropertyVO::getProperty, Function.identity())));
                for (RoomEnvVO roomEnvVO : roomList) {
//                    //查询灯带
//                    List<RoomLightStatusVO> lightStatusList = roomLightMap.getOrDefault(roomEnvVO.getRoomId(), new ArrayList<>());

                    //查属性
                    Map<String, RoomDevicePropertyVO> propertyMap = roomPropertyMap.get(roomEnvVO.getRoomId());
                    if (!ObjectUtils.isEmpty(propertyMap)){

                        //氧气
                        RoomDevicePropertyVO o2 = propertyMap.get(PropertyEnum.O2_CONETENT.getCode());
                        roomEnvVO.setO2(ObjectUtils.isEmpty(o2) ? null : o2.getValue());

                        //氮气
                        RoomDevicePropertyVO n2 = propertyMap.get(PropertyEnum.N2_CONETENT.getCode());
                        roomEnvVO.setN2(ObjectUtils.isEmpty(n2) ? null : n2.getValue());

                        //笑气
                        RoomDevicePropertyVO n2o = propertyMap.get(PropertyEnum.N2O_CONETENT.getCode());
                        roomEnvVO.setN2o(ObjectUtils.isEmpty(n2o) ? null : n2o.getValue());

                        //氩气
                        RoomDevicePropertyVO ar = propertyMap.get(PropertyEnum.AR_CONETENT.getCode());
                        roomEnvVO.setAr(ObjectUtils.isEmpty(ar) ? null : ar.getValue());

                        //负压真空吸引
                        RoomDevicePropertyVO npvs = propertyMap.get(PropertyEnum.NEGATIVE_PRESSURE_VACUUM_SUCTION_CONTENT.getCode());
                        roomEnvVO.setNpvs(ObjectUtils.isEmpty(npvs) ? null : npvs.getValue());

                        //二氧化碳
                        RoomDevicePropertyVO co2 = propertyMap.get(PropertyEnum.CO2_CONTENT.getCode());
                        roomEnvVO.setCo2(ObjectUtils.isEmpty(co2) ? null : co2.getValue());

                        //压缩气体
                        RoomDevicePropertyVO compressedGas = propertyMap.get(PropertyEnum.COMPRESSED_GAS_CONTENT.getCode());
                        roomEnvVO.setCompressedGas(ObjectUtils.isEmpty(compressedGas) ? null : compressedGas.getValue());

                        //系统故障
                        RoomDevicePropertyVO systemFailure = propertyMap.get(PropertyEnum.SYSTEM_FAILURE.getCode());
                        roomEnvVO.setSystemFailure(ObjectUtils.isEmpty(systemFailure) ? null : systemFailure.getValue());

                        //消防状态
                        RoomDevicePropertyVO fireStatus = propertyMap.get(PropertyEnum.FIRE_STATUS.getCode());
                        roomEnvVO.setFireStatus(ObjectUtils.isEmpty(fireStatus) ? null : fireStatus.getValue());

                        //IT故障
                        RoomDevicePropertyVO itMalfunction = propertyMap.get(PropertyEnum.IT_MALFUNCTION.getCode());
                        roomEnvVO.setItMalfunction(ObjectUtils.isEmpty(itMalfunction) ? null : itMalfunction.getValue());

                        //当前温度
                        RoomDevicePropertyVO wend = propertyMap.get(PropertyEnum.TEMPERATURE.getCode());
                        roomEnvVO.setWend(ObjectUtils.isEmpty(wend) ? null : wend.getValue());

                        //当前湿度
                        RoomDevicePropertyVO shid = propertyMap.get(PropertyEnum.HUMIDITY.getCode());
                        roomEnvVO.setShid(ObjectUtils.isEmpty(shid) ? null : shid.getValue());

                        //当前压差
                        RoomDevicePropertyVO pressure = propertyMap.get(PropertyEnum.PRESSURE.getCode());
                        roomEnvVO.setPressure(ObjectUtils.isEmpty(pressure) ? null : pressure.getValue());

                        //温度更新时间
                        roomEnvVO.setUpdateTimeWend(ObjectUtils.isEmpty(wend) ? null : DateUtil.formatDateTime(wend.getCreateTime()));

                        //压差更新时间
                        roomEnvVO.setUpdateTimePressure(ObjectUtils.isEmpty(pressure) ? null : DateUtil.formatDateTime(pressure.getCreateTime()));


                        //获取灯带状态列表
                        List<RoomLightStatusVO> roomLightStatusVOList = Stream.of(PropertyEnum.DENGDAI1.getCode(), PropertyEnum.DENGDAI2.getCode()).map(code -> {

                            //房间灯光状态对象
                            RoomLightStatusVO roomLightStatusVO = new RoomLightStatusVO();

                            //获取对应灯带的属性VO
                            RoomDevicePropertyVO dengdai = propertyMap.get(code);

                            //赋值灯光状态对象
                            roomLightStatusVO.setRoomId(roomEnvVO.getRoomId());
                            roomLightStatusVO.setProperty(code);
                            roomLightStatusVO.setDeviceId(dengdai == null ? null : dengdai.getDeviceId());
                            roomLightStatusVO.setState("online");
                            roomLightStatusVO.setValue(dengdai != null && dengdai.getValue().compareTo("0") > 0);

                            //返回房间灯光状态对象
                            return roomLightStatusVO;
                        }).collect(Collectors.toList());

                        //设置灯带状态
                        roomEnvVO.setLightStatusList(roomLightStatusVOList);


                        //查询空调开关
                        RoomAirConditionSwitchVO roomAirConditionSwitchVO =  new RoomAirConditionSwitchVO();

                        //空调开关状态
                        RoomDevicePropertyVO ktkgzt = propertyMap.get(PropertyEnum.KTKGZT.getCode());
                        roomAirConditionSwitchVO.setKtkgzt(ktkgzt == null ? null : ktkgzt.getValue());
                        roomAirConditionSwitchVO.setRoomId(roomEnvVO.getRoomId());
                        roomAirConditionSwitchVO.setDeviceId(ktkgzt == null ? null : ktkgzt.getDeviceId());

                        //实际温度
                        RoomDevicePropertyVO actualWend = propertyMap.get(PropertyEnum.TEMPERATURE.getCode());
                        roomAirConditionSwitchVO.setActualWend(actualWend == null ? null : actualWend.getValue());

                        //实际湿度
                        RoomDevicePropertyVO actualShid = propertyMap.get(PropertyEnum.HUMIDITY.getCode());
                        roomAirConditionSwitchVO.setActualShid(actualShid == null ? null : actualShid.getValue());

                        //设置温度
                        RoomDevicePropertyVO settingWend = propertyMap.get(PropertyEnum.SETTING_TEMPERATURE.getCode());
                        roomAirConditionSwitchVO.setSettingWend(settingWend == null ? null : settingWend.getValue());

                        //设置湿度
                        RoomDevicePropertyVO settingShid = propertyMap.get(PropertyEnum.SETTING_HUMIDITY.getCode());
                        roomAirConditionSwitchVO.setSettingShid(settingShid == null ? null : settingShid.getValue());

                        //设置状态
                        roomAirConditionSwitchVO.setState("online");

                        //设置房间的空调数据
                        roomEnvVO.setAirConditionSwitch(roomAirConditionSwitchVO);
                    }
                }
            }
            defaultDeviceService.wrapAddr(roomList);
            page.setRecords(roomList);
        }
        return page;
    }

    public void exportRoomEnv(RoomEnvQuery query, HttpServletResponse response) {
        query.setDisAblePage(true);
        List<RoomEnvVO> list = pageRoomEnv(query).getRecords();
        List<RoomEnvExportVO> dataList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(list)){
            RoomEnvExportVO temp = null;
            for (RoomEnvVO roomEnvVO : list) {
                temp = new RoomEnvExportVO();
                temp.setFloorName(roomEnvVO.getFloorName());
                temp.setRoomName(roomEnvVO.getRoomName());
                temp.setWend(roomEnvVO.getWend());
                temp.setShid(roomEnvVO.getShid());
                temp.setPressure(roomEnvVO.getPressure());
                temp.setUpdateTimeWend(roomEnvVO.getUpdateTimeWend());
                temp.setUpdateTimePressure(roomEnvVO.getUpdateTimePressure());
                dataList.add(temp);
            }
        }
        String fileName = "导出环境参数" + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
        EasyExcelUtil.exportExcelData(response,fileName,dataList,RoomEnvExportVO.class);
    }

    public Map<String,ChartVO> listChartData(RoomEnvChartQuery query) {
        Map<String,ChartVO> map = new HashMap<>();
        query.setPropertyList(Arrays.asList(
                PropertyEnum.PRESSURE.getCode(),
                PropertyEnum.TEMPERATURE.getCode(),
                PropertyEnum.HUMIDITY.getCode()
        ));
        query.setExcludeSpecialityCode(SpecialityModelCodeEnum.smart_lighting.getCode());
        List<DeviceVO> deviceList = roomEnvMapper.listDevice(query);
        List<Properties> list = new ArrayList<>();
        if (!ObjectUtils.isEmpty(deviceList) && deviceList.stream().anyMatch(Objects::nonNull)){
            Map<String, List<String>> productDeviceIdListMap = deviceList.stream().collect(Collectors.groupingBy(DeviceVO::getProductId, Collectors.mapping(DeviceVO::getId, Collectors.toList())));
            List<RoomEnvRecordQuery> queryList = new ArrayList<>();
            for (String productId : productDeviceIdListMap.keySet()) {

                //超级表全称 即数据库名.表名
                String fullSuperTableName = defaultDeviceService.getTableName(productId);

                //超级表名称
                String superTableName = fullSuperTableName.split("\\.")[1];

                //判断超级表是否存在
                if (taosService.checkStable(tdEngineDbName, superTableName)){

                    //超级表存在再将查询条件添加到查询条件列表中
                    RoomEnvRecordQuery roomEnvRecordQuery = new RoomEnvRecordQuery();
                    roomEnvRecordQuery.setRoomId(query.getRoomId());
                    roomEnvRecordQuery.setStartTime(DateUtil.parseDateTime(query.getStartTime()).getTime());
                    roomEnvRecordQuery.setEndTime(DateUtil.parseDateTime(query.getEndTime()).getTime());
                    roomEnvRecordQuery.setSpecialityCode(query.getSpecialityCode());
                    roomEnvRecordQuery.setPropertyList(query.getPropertyList());
                    roomEnvRecordQuery.setTableName(fullSuperTableName);
                    roomEnvRecordQuery.setDeviceIdList(productDeviceIdListMap.get(productId));
                    queryList.add(roomEnvRecordQuery);
                }

            }

            //若查询条件非空、查询所有设备对应的属性值信息
            if (!ObjectUtils.isEmpty(queryList)){
                list = roomEnvMapper.listRecord(queryList);
            }
        }

        if (!ObjectUtils.isEmpty(list)){
            Map<String, List<Properties>> propertiesMap = list.stream().collect(Collectors.groupingBy(Properties::getProperty));
            for (String key : propertiesMap.keySet()) {
                map.put(key,new ChartVO(key,PropertyEnum.getVal(key),PropertyEnum.getName(key),propertiesMap.get(key)));
            }
        }
        return map;
    }
}
